/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.adaptor;

//import Inspur.Gsp.Caf.Generator.ClassGenerator.*;
//import Inspur.Gsp.Caf.Generator.ClassMethodGenerator.*;
//import Inspur.Gsp.Cef.Api.Attribute.*;
//import Inspur.Gsp.Cef.Repository.*;
//import Inspur.Gsp.Cef.RTGenerator.Common.*;
//import Inspur.Gsp.Cef.RTGenerator.RepositoryGen.*;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.caf.generator.item.ClassGenerator;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityGeneratorContext;
import com.inspur.edp.cef.generator.repository.adaptor.method.GetAssosPropDBMappingGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.GetLogicDeleteInfoGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.GetReposAssosPropDBMappingGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.InitAssosGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.BasePropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.BinaryPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.BoolPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.ClobPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.CreateUdtDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.DecimalPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.EntityCreateAssocationDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.EntityCreateEnumDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.EntityGetAssocationDBMappingMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.GetDateTimePropetyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.IntPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.NormalPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createpropertydefmethod.StringPropertyCreateDefMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.readproperty.DataTypeReadPropertyGenerator;
import com.inspur.edp.cef.generator.repository.dac.DataTypeDacGenContext;
import com.inspur.edp.cef.repository.assembler.AssociationInfo;
import com.inspur.edp.cef.repository.dbcolumninfo.DbColumnInfoCollection;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import java.util.ArrayList;

public abstract class DataTypeAdaptorGenerator extends ClassGenerator {
	protected DataTypeDacGenContext DacContext;
	protected DbColumnInfoCollection DbColumns;
	protected IGspCommonDataType gspCommonDataType;
//	protected java.util.ArrayList<AssociationInfo> associationInfos = new java.util.ArrayList<AssociationInfo>();

	protected DataTypeAdaptorGenerator(IGspCommonDataType gspCommonDataType, DataTypeDacGenContext dacContext, String nodeCode) {
		super(dacContext.getReposContext().getCefContext().getCefGenContext().getCefCoreGenCtx().getCompilationUnitInfo());
		this.gspCommonDataType = gspCommonDataType;
		NodeCode = dacContext.getReposContext().getCefContext().getCefGenContext().getCommonDataType().getCode();
		DacContext = dacContext;
	}

	protected String NodeCode;

	@Override
	protected java.util.ArrayList<ClassMethodGenerator> createMethodGenerators() {

		ArrayList<ClassMethodGenerator> methods = super.createMethodGenerators();
		if (methods == null) {
			methods = new java.util.ArrayList<ClassMethodGenerator>();
		}
		addGetPropertyValueGenerators(methods);
		addReadPropertyGenerators(methods);
//		InitAssosGenerator initAssoGen = new InitAssosGenerator(DacContext.getReposContext().getCefContext().getCefGenContext(), gspCommonDataType, null);
//		methods.add(initAssoGen);

		if(gspCommonDataType instanceof GspBizEntityObject){
			if(((GspBizEntityObject) gspCommonDataType).getLogicDeleteControlInfo() != null && ((GspBizEntityObject) gspCommonDataType).getLogicDeleteControlInfo().getEnableLogicDelete()) {
				methods.add(new GetLogicDeleteInfoGenerator((GspBizEntityObject) gspCommonDataType));
			}
		}

		ArrayList<IGspCommonField> commonFields = new ArrayList<>();
		for(IGspCommonField commonField:gspCommonDataType.getContainElements()){
			if(commonField.getChildAssociations() != null && commonField.getChildAssociations().size() > 0){
				commonFields.add(commonField);
			}

		}

//		if(commonFields !=null && commonFields.size() >0){
//			GetAssosPropDBMappingGenerator getAssosPropDBMappingGenerator = new GetAssosPropDBMappingGenerator(commonFields);
//			methods.add(getAssosPropDBMappingGenerator);
//		}
		return methods;
	}

//	public GetReposAssosPropDBMappingGenerator getReposAssosPropDBMappingGenerator(){
//		GetReposAssosPropDBMappingGenerator getReposAssosPropDBMappingGenerator = new GetReposAssosPropDBMappingGenerator();
//		return getReposAssosPropDBMappingGenerator;
//	}
	@Override
	protected void beforeInitialize() {
		super.beforeInitialize();
	}


	private void addGetPropertyValueGenerators(java.util.ArrayList<ClassMethodGenerator> gens) {
		for(IGspCommonField gspCommonField: gspCommonDataType.getContainElements()){
			addGetPropertyValueGenerator(gens, gspCommonField);
		}
	}

	protected void addGetPropertyValueGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField gspCommonField) {


		String propertyName = gspCommonField.getLabelID();

		if (gspCommonDataType instanceof UnifiedDataTypeDef) {
			if (gspCommonDataType instanceof ComplexDataTypeDef) {//多值udt不包含
				if(((ComplexDataTypeDef)gspCommonDataType).getDbInfo().getMappingType() == ColumnMapType.SingleColumn){
					return;
				}
			}
		}
//		if(gspCommonField.getIsUdt()){
//			UnifiedDataTypeDef udt = (UnifiedDataTypeDef)DacContext.getReposContext().getCefContext().getCefGenContext().getMetadataJitContext().getMetadata(gspCommonField.getUdtID()).getContent();
//			gens.add(new CreateUdtDefMethodGenerator(gspCommonField, udt, DacContext, NodeCode));
//			//应该是判断所引用的udt对象的值？？
//			if (gspCommonDataType instanceof ComplexDataTypeDef) {//多值udt不包含
//				return;
//			}
//			if(gspCommonField.getObjectType() == GspElementObjectType.Association){
//				addAssgetDBMappingGenerator(gens, gspCommonField);
//			}
//			return;
//		}
//		if (gspCommonField.getIsVirtual() || gspCommonField.getObjectType() == GspElementObjectType.DynamicProp) {
//			return;
//		}
//		if (gspCommonField.getObjectType() == GspElementObjectType.Association) {
//			addAssgetPropValueGenerator(gens, gspCommonField);
//			addAssgetDBMappingGenerator(gens, gspCommonField);
//			return;
//		} else if (gspCommonField.getObjectType() == GspElementObjectType.Enum) {
//			addEnumgetPropValueGenerator(gens, gspCommonField);
//			return;
//		} else {
//			addNormalgetPropValueGenerator(gens, gspCommonField);
//		}
	}

	private String getAssoClassName(String labelId){
		return DacContext.getReposContext().getCefContext().getCefGenContext().
				getEntityGenContext().getDataTypeGenContexts().get(NodeCode).getAssociationTypes().get(labelId);
	}

	protected final void addAssgetPropValueGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField gspCommonField) {
		GspAssociation associationInfo = getAssociationInfo(gspCommonField);
		gens.add(new EntityCreateAssocationDefMethodGenerator(DacContext.getReposContext().getCefContext().getCefGenContext(), gspCommonDataType, gspCommonField, associationInfo, getAssoClassName(gspCommonField.getLabelID()), gspCommonField.getLabelID()));
	}


//	private void addAssgetDBMappingGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField gspCommonField) {
//		GspAssociation associationInfo = getAssociationInfo(gspCommonField);
//		gens.add(new EntityGetAssocationDBMappingMethodGenerator(DacContext.getReposContext().getCefContext().getCefGenContext(), gspCommonDataType, associationInfo,  gspCommonField.getLabelID()));
//	}

	protected GspAssociation getAssociationInfo(IGspCommonField field){
		GspAssociation gspAssociation = null;
		if (field.getHasAssociation()){
			if (field.getChildAssociations() == null || field.getChildAssociations().size() < 1) {
				throw new RuntimeException("没有找到关联信息" + field.getLabelID());
			}
			for (GspAssociation association : field.getChildAssociations()) {
				gspAssociation = association;
				break;
			}
		}
		return gspAssociation;
	}

	protected final void addEnumgetPropValueGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField item) {
		gens.add(enumGetPropValueGenerator(gens,item));
	}

	protected BasePropertyCreateDefMethodGenerator enumGetPropValueGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField gspCommonField){
		String propertyClassName = getEntityContext().getFieldTypeInfo(NodeCode, gspCommonField).getTypeFullName();
		return new EntityCreateEnumDefMethodGenerator(gspCommonField, gspCommonField.getLabelID(), propertyClassName);
	}

	private EntityGeneratorContext getEntityContext(){
		return DacContext.getReposContext().getCefContext().getEntityGeneratorContext();
	}

	protected void addNormalgetPropValueGenerator(java.util.ArrayList<ClassMethodGenerator> gens, IGspCommonField gspCommonField) {
//		if (gspCommonField.getMDataType() == GspElementDataType.String || gspCommonField.getMDataType() == GspElementDataType.Text) {
//			gens.add(getStringPropCreateDefMethodGenerator(gspCommonField));
//		} else if (gspCommonField.getMDataType() == GspElementDataType.Boolean) {
//			gens.add(new BoolPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField));
//		} else if (gspCommonField.getMDataType() == GspElementDataType.Integer) {
//			gens.add(new IntPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField));
//		} else if (gspCommonField.getMDataType() == GspElementDataType.Date ||gspCommonField.getMDataType() == GspElementDataType.DateTime) {
//			gens.add(new GetDateTimePropetyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField));
//		} else if (gspCommonField.getMDataType() == GspElementDataType.Decimal) {
//			gens.add(new DecimalPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField));
//		} else if (gspCommonField.getMDataType() == GspElementDataType.Binary) {
//			gens.add(new BinaryPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField));
//		} else {
////			throw new RuntimeException("AddNormalGetPropValueGenerator");
//		}
	}

	protected  NormalPropertyCreateDefMethodGenerator getStringPropCreateDefMethodGenerator(IGspCommonField gspCommonField)
	{
		if(gspCommonField.getMDataType() == GspElementDataType.Text)
		{
			return new ClobPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField);

		}
		else {
			return new StringPropertyCreateDefMethodGenerator(gspCommonField.getLabelID(), gspCommonField);
		}
	}


	private void addReadPropertyGenerators(java.util.ArrayList<ClassMethodGenerator> gens) {
		gens.add(getReadPropertyGenerator());
	}

	public abstract DataTypeReadPropertyGenerator getReadPropertyGenerator();

	//protected override List<ClassMethodGenerator> createMethodGenerators()
	//{
	//    var getValueGenerator = new GetValueGenerator(DacContext, new DbColumnInfoCollection(), MappingAttributes);
	//    return new List<ClassMethodGenerator>(){ getValueGenerator };
	//}
}
